/**
 * 1.创建一个新的axios实例
 * 2.请求拦截器, 如果有token进行头部携带
 * 3.响应拦截器: (1): 剥离无效数据,  (2): 处理token失效
 * 4.导出一个函数, 调用当前的axios实例发请求, 返回值promise
 */

import axios from 'axios'
import store from '@/store'
import router from '@/router'

// 导入 NProgress 包对应的JS和CSS
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
// import { useRouter } from 'vue-router'

// 导出基准地址, 原因: 其他地方不是通过axios发请求的时, 不一定用基准地址, 如上传图片
export const baseURL = 'http://pcapi-xiaotuxian-front-devtest.itheima.net/'
const service = axios.create({
  baseURL,
  timeout: 5000
})

service.interceptors.request.use((config) => {
  NProgress.start()
  // 拦截业务请求
  // 进行请求配置的修改
  // 如果本地有token就在头部携带

  // 1.获取用户信息对象
  const { profile } = store.state.user
  // 2.判断是否有token
  if (profile.token) {
    // 3.设置token
    config.headers.Authorization = `Bearer ${profile.token}`
  }

  return config
}, (err) => {
  return Promise.reject(err)
})

service.interceptors.response.use((res) => {
  NProgress.done()
  // res => res.data 取出data数据,  将来调用接口的时候字节拿到的就是后台数据
  return res.data
}, (err) => {
  NProgress.done()
  // 401状态码, 进入该函数
  if (err.response && err.response.status === 401) {
    // const router = useRouter()
    // 1.清空本地无效用户信息, 传递一个空对象, 就清除本地无效用户信息了
    store.commit('user/setUser', {})
    // 2.跳转到登录页码,
    // 在组件中: `/user?a=10` $route.path === /user  $route.fullPath === /user?a=10
    // 在js模块中: router.currentRoute.fullPath 就是当前路由地址: router.currentRoute 是ref响应式对象
    // encodeURIComponent 将获取到fullPath转码(特殊字符存在 = ), 防止解析出错
    const fullPath = encodeURIComponent(router.currentRoute.value.fullPath)
    router.push(`/login?redirectUrl=${fullPath}`)
    // 3.跳转需要传参(当前路由地址)给登录页码
  }
  return Promise.reject(err)
})

// 请求工具函数
export default (url, method, submitData) => {
  // 负责发请求, 请求地址, 请求方式, 提交的数据
  return service({
    url,
    method,
    // 1.如果是get请求, 需要使用params来传递submitData    ?a=10&b=20
    // 2.如果不是get请求, 需要使用data来传递submitData     请求体
    // const a = { name: 100 } a.name | a[10 > 9 ? 'name':'age']
    // ES6语法, 属性名表达式. 允许字面量定义对象时, 把表达式放到方括号[]内
    // let propKey = 'foo';  let obj = { [propKey]: true }, 表达式还可以用于方法名!!!
    // [] -> 设置一个动态的key, 写js表达式, js表达式的执行结果当做key
    // method参数: get、Get、GET 转换成小写再来判断,  js中没有equalsIs吗
    [method.toLowerCase() === 'get' ? 'params' : 'data']: submitData
  })
}
